<template>
  <el-form ref="newForm" :model="newForm" label-width="120px">
    <el-form-item
      label="文章标题："
      prop="title"
      :rules="[{ required: true, message: '请输入文章标题' }]"
    >
      <el-input
        placeholder="请输入"
        type="text"
        v-model.trim="newForm.title"
      ></el-input>
    </el-form-item>
    <el-form-item
      label="文章简介："
      prop="introduction"
      :rules="[{ required: true, message: '请输入文章简介' }]"
    >
      <el-input
        placeholder="请输入"
        type="textarea"
        :rows="2"
        v-model.trim="newForm.introduction"
      ></el-input>
    </el-form-item>
    <el-form-item
      label="文章分类："
      prop="knowledgeTypeId"
      :rules="[{ required: true, message: '请输入文章简介' }]"
    >
      <el-select v-model="newForm.knowledgeTypeId" placeholder="请选择">
        <el-option
          :label="item.name"
          :value="item.id"
          v-for="(item, index) in cateList"
          :key="index"
        ></el-option>
      </el-select>
    </el-form-item>
    <el-form-item
      label="文章来源："
      prop="source"
      :rules="[{ required: true, message: '请输入文章来源' }]"
    >
      <el-input
        placeholder="请输入"
        type="text"
        v-model.trim="newForm.source"
      ></el-input>
    </el-form-item>
    <el-form-item label="文章类型：">
      <el-radio-group v-model="type">
        <el-radio label="1">图文</el-radio>
        <el-radio label="2">视频</el-radio>
      </el-radio-group>
    </el-form-item>
    <template v-if="type == 1">
      <el-form-item label="文章封面图：">
        <el-upload
          class="avatar-uploader pic-uploader"
          :action="config.uploadUrl"
          :show-file-list="false"
          :on-success="handleUploadImgSuccess"
          accept="image/*"
          :data="{ token: siteInfos.token }"
        >
          <img v-if="newForm.path" :src="newForm.path" class="avatar" />
          <i v-else class="el-icon-plus avatar-uploader-icon"></i>
        </el-upload>
      </el-form-item>
      <el-form-item
        label="文章内容："
        prop="content"
        :rules="[{ required: true, message: '请输入文章内容' }]"
      >
        <div ref="editor"></div>
      </el-form-item>
    </template>
    <template v-else>
      <el-form-item
        label="上传视频："
        prop="path"
        :rules="[{ required: true, message: '请上传视频' }]"
      >
        <el-upload
          class="avatar-uploader pic-uploader"
          :action="config.uploadUrl"
          :show-file-list="false"
          :on-success="handleUploadVideoSuccess"
          :before-upload="beforeVideoUpload"
          accept=".mp4"
          :data="{ token: siteInfos.token }"
        >
          <video v-if="newForm.path" :src="newForm.path" class="avatar"></video>
          <i v-else class="el-icon-plus avatar-uploader-icon"></i>
        </el-upload>
      </el-form-item>
      <el-form-item label="视频封面图：">
        <el-image
          style="
            width: 200px;
            height: 200px;
            border: 1px dashed #eee;
            border-radius: 5px;
          "
          :src="newForm.cover"
          v-if="newForm.cover"
          fit="scale-down"
        >
        </el-image>
        <p v-else>请上传视频</p>
      </el-form-item>
    </template>
  </el-form>
</template>
<script>
import videoTools from "@/assets/js/videoTools.js";
import WangEditor from "wangeditor";
import { mapState } from "vuex";

const { $, DropListMenu } = WangEditor;

// 第一，菜单 class ，Button 菜单继承 BtnMenu class
class AlertMenu extends DropListMenu {
  constructor(editor) {
    // data-title属性表示当鼠标悬停在该按钮上时提示该按钮的功能简述
    const $elem = $(
      '<div class="w-e-menu" data-title="首行缩进"><i class="w-e-icon-indent-increase"></i></div>'
    );
    // droplist 配置
    const dropListConf = {
      width: 100,
      title: "首行缩进",
      type: "list",
      list: [
        {
          $elem: $(
            '<p><i class="w-e-icon-indent-increase w-e-drop-list-item"></i>首行缩进</p>'
          ),
          value: "2em",
        },
        {
          $elem: $(
            '<p><i class="w-e-icon-indent-decrease w-e-drop-list-item"></i>取消缩进</p>'
          ),
          value: "",
        },
      ],
      // droplist 每个 item 的点击事件
      clickHandler: (value) => {
        // value 参数即 dropListConf.list 中配置的 value
        this.command(value);
      },
    };
    super($elem, editor, dropListConf);
  }

  command(value) {
    // 设置标题
    // 判断是否有子元素 有一个官方提供的结束节点不准确的Bug
    if (
      this.editor.selection.getSelectionContainerElem().elems[0].children
        .length > 0
    ) {
      let fir = 0;
      var start = false;
      let isAllBr = 0;
      let isVali = false;
      // 判断是否全部是BR 即无格式文本
      for (let e of this.editor.selection.getSelectionContainerElem().elems[0]
        .children) {
        if (e.tagName === "BR") {
          isAllBr++;
        }
      }
      if (
        isAllBr ===
        this.editor.selection.getSelectionContainerElem().elems[0].children
          .length
      )
        isVali = true;
      // 对无格式文本进行缩进处理
      // 如果是<br>
      // 选中节点无法选到br 进行和取消的逻辑
      // 判断是否已是选中节点
      if (isVali) {
        for (let e of this.editor.selection.getSelectionContainerElem().elems[0]
          .children) {
          if (e.tagName === "BR") {
            if (value === "2em") {
              fir += 1;
              if (fir === 1) {
                this.editor.selection.getSelectionContainerElem().elems[0].style.textIndent =
                  value;
              }
              const indentP = document.createElement("span");
              indentP.style.display = "inline-block";
              indentP.style.width = value;
              indentP.className = "indentP";
              const theBr = document.createElement("br");
              this.editor.selection
                .getSelectionContainerElem()
                .elems[0].replaceChild(indentP, e);
              this.editor.selection
                .getSelectionContainerElem()
                .elems[0].insertBefore(theBr, indentP);
            }
          }
        }
      } else {
        let elseIndex = 0;
        // 正常文本 以及无格式文本取消缩进逻辑
        for (let e of this.editor.selection.getSelectionContainerElem().elems[0]
          .children) {
          // 如果是无格式文本
          if (e.className === "indentP") {
            elseIndex++;
            if (elseIndex === 1) {
              this.editor.selection.getSelectionContainerElem().elems[0].style.textIndent =
                value;
            }
            this.editor.selection
              .getSelectionContainerElem()
              .elems[0].removeChild(e);
            continue;
          }
          // 选区的开始节点
          if (e === this.editor.selection.getSelectionStartElem().elems[0]) {
            start = true;
          }
          // 如果已是选中节点，则开始进行缩进
          if (start) {
            e.style.textIndent = value;
          }
          // 选区的结束节点 跳出循环
          if (e === this.editor.selection.getSelectionEndElem().elems[0]) {
            break;
          }
        }
      }
    } else {
      this.editor.selection.getSelectionContainerElem().elems[0].style.textIndent =
        value;
    }
  }

  // 删除这段代码会报错
  tryChangeActive() {
    // const reg = /^h/i
    // const cmdValue = this.editor.cmd.queryCommandValue('indent')
    // if (reg.test(cmdValue)) {
    //     // 选区处于标题内，激活菜单
    //     this.active()
    // } else {
    //     // 否则，取消激活
    //     this.unActive()
    // }
    // this.active()
  }
}
// 菜单 key ，各个菜单不能重复
const menuKey = "textIndent";
// 注册菜单
WangEditor.registerMenu(menuKey, AlertMenu);

let editor;
export default {
  data() {
    return {
      newForm: {
        content: "",
      },
      type: "1",
    };
  },
  props: {
    cateList: {
      type: Array,
      default() {
        return [];
      },
      required: true,
    },
    activeData: {
      type: Object,
      default() {
        return null;
      },
    },
  },
  computed: {
    ...mapState(["siteInfos"]),
  },
  watch: {
    type(value) {
      if (value == 1) {
        this.$nextTick(() => {
          this.initEditor();
        });
      }
    },
  },
  created() {
    if (this.activeData) {
      this.initForm();
    }
  },
  mounted() {
    if (this.type == 1) {
      this.initEditor();
    }
  },
  methods: {
    initForm() {
      let {
        id,
        title,
        introduction,
        content,
        source,
        knowledgeType,
        path,
        cover,
      } = this.activeData;
      this.newForm = { id, title, introduction, content, source, path, cover };
      this.newForm.knowledgeTypeId = knowledgeType;
      if (this.newForm.cover === "null") {
        this.newForm.cover = "";
      }
      if (this.newForm.path === "null") {
        this.newForm.path = "";
      }
      if (this.newForm.cover) {
        this.type = "2";
      }
    },
    initEditor() {
      editor = new WangEditor(this.$refs.editor);
      editor.config.onchange = (html) => {
        this.newForm.content = html;
      };
      editor.config.menus = [
        "head",
        "bold",
        "fontSize",
        "fontName",
        "italic",
        "underline",
        "strikeThrough",
        "lineHeight",
        "foreColor",
        "backColor",
        "link",
        "list",
        "todo",
        "justify",
        "quote",
        "emoticon",
        "image",
        "video",
        "table",
        "code",
        "splitLine",
        "undo",
        "redo",
      ];
      editor.config.colors = [
        "#000000",
        "#ff0000",
        "#00ff00",
        "#0000ff",
        "#ffff00",
        "#00ffff",
        "#ff00ff",
        "#666666",
        "#999999",
        "#dddddd",
      ];
      editor.config.uploadImgMaxLength = 1;
      editor.config.uploadImgMaxSize = 10 * 1024 * 1024; // 2M
      editor.config.customUploadImg = (resultFiles, insertImgFn) => {
        this.uploadImg(resultFiles[0], (url) => {
          insertImgFn(url);
        });
      };
      editor.config.customUploadVideo = (resultFiles, insertVideoFn) => {
        this.uploadImg(resultFiles[0], (url) => {
          insertVideoFn(url);
        });
      };
      editor.create();
      editor.txt.html(this.newForm.content);
    },
    uploadImg(file, cbk) {
      const formData = new FormData();
      formData.append("file", file);
      const xhr = new XMLHttpRequest();
      this.openFullLoading("正在上传");
      xhr.open("POST", this.config.uploadUrl, true);
      xhr.send(formData);
      xhr.onreadystatechange = () => {
        if (xhr.readyState == 4 && (xhr.status == 200 || xhr.status == 304)) {
          let uploadRes = JSON.parse(xhr.responseText);
          if (uploadRes.code == 0) {
            cbk && cbk(uploadRes.data.filePath);
            this.newForm.cover = uploadRes.data.filePath;
          }
          this.closeFullLoading("正在上传");
        }
      };
    },
    handleUploadImgSuccess(res, file) {
      this.$set(this.newForm, "path", res.data.filePath);
    },
    beforeVideoUpload(file) {
      const isLimit = file.size / 1024 / 1024 < 10;
      this.openFullLoading("正在上传");
      // if (!isLimit) {
      //     this.$message.error('上传头像图片大小不能超过 10MB!');
      // }
      let url = URL.createObjectURL(file);
      this.cutVideoCover(url, 0);
      return true;
    },
    handleUploadVideoSuccess(res, file) {
      this.$set(this.newForm, "path", res.data.filePath);
      this.closeFullLoading();
    },
    cutVideoCover(url) {
      videoTools.GetVideoCover({
        url: url,
        time: 3,
        success: (res) => {
          const blob = videoTools.transformBase64ToBlob(res.base64);
          this.uploadImg(blob, (url) => {
            this.newForm.cover = url;
          });
        },
      });
    },
    handleRemove(file, fileList) {
      this.newForm.img = "";
    },
    submitAction() {
      this.$refs["newForm"].validate((valid) => {
        if (valid) {
          this.$emit("submitting");
          let params = Object.assign(
            {
              publisher: this.$store.state.siteInfos.userRealName,
            },
            this.newForm
          );
          this.$ajax({
            url: "/noticeAnnouncement/noticeAnnouncement/addOrUpdateArticle",
            method: "post",
            data: params,
          }).then(
            (data) => {
              this.$emit("success", data);
              this.$message.success("保存成功");
            },
            (error) => {
              this.$emit("fail");
              this.$message.error(error.msg);
            }
          );
        } else {
          return false;
        }
      });
    },
  },
};
</script>
<style></style>
